package cheme.ProcessModel.Subprocess;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

import cheme.ProcessModel.AbstractParent;
import cheme.ProcessModel.IModelElement;
import cheme.ProcessModel.IParent;
import cheme.ProcessModel.ITranslatable;
import cheme.ProcessModel.XmlHelper;
import cheme.ProcessModel.Visitors.IModelVisitor;


public class Subprocess extends AbstractParent<ITranslatable> implements ISubprocess
{
	/*
	 * Serialization version identifier. (Set to default for now)
	 */
	
	private static final long serialVersionUID = 1L;

	IParent parent;
	
	/*
	 * The geometry of the node.
	 */
	private Rectangle bounds;
	
	public Subprocess()
	{
		this((IModelElement)null);
	}
	
	public Subprocess(IModelElement parent)
	{
		super(parent);
		initializeBounds();
	}
	
	public Subprocess(Element xmlDoc)
	{
		super(xmlDoc);
		initializeBounds();
		
		Element position = (Element)xmlDoc.getElementsByTagName("Position").item(0);
		Element xPos = (Element)position.getElementsByTagName("X").item(0);
		Element yPos = (Element)position.getElementsByTagName("Y").item(0);
		Element width = (Element)position.getElementsByTagName("Width").item(0);
		Element height = (Element)position.getElementsByTagName("Height").item(0);
		
		int x = Integer.parseInt(xPos.getFirstChild().getNodeValue());
		int y = Integer.parseInt(yPos.getFirstChild().getNodeValue());
		int w = Integer.parseInt(width.getFirstChild().getNodeValue());
		int h = Integer.parseInt(height.getFirstChild().getNodeValue());
		
		this.bounds.x = x;
		this.bounds.y = y;
		this.bounds.width = w;
		this.bounds.height = h;
	}
		
	private void initializeBounds()
	{
		bounds = new Rectangle(10, 10, 200, 100);
	}
	
	public Rectangle getBounds()
	{
		return bounds.getCopy();
	}

	public void setBounds(Rectangle bounds)
	{
		if(!this.bounds.equals(bounds))
		{
			Rectangle oldBounds = new Rectangle(this.bounds);
			this.bounds = bounds;

			firePropertyChange(P_CONSTRAINT, oldBounds, bounds);
		}
	}
	
	public Point getLocation()
	{
		return bounds.getTopLeft();
	}
	
	public void setLocation(Point location)
	{
		bounds.setLocation(location);
		firePropertyChange(P_CONSTRAINT, null, bounds);
	}
	
	public Dimension getSize()
	{
		return new Dimension(50,50);
	}
	
	public void setSize(Dimension size)
	{
		bounds.setSize(size);
		firePropertyChange(P_CONSTRAINT, null, bounds);
	}
	
	public Object accept(IModelVisitor ruleChecker)
	{
		return ruleChecker.visit(this);
	}
	
	public String toXML()
	{
		String xml = super.toXml("SubProcess");
		
		Document doc = (Document)XmlHelper.xmlFromString(xml);
		
		//create new root element to contain the width, height, x and y values of the subprocess
		Element root = doc.getDocumentElement();
		Element pos = doc.createElement("Position");
		Element xElement = doc.createElement("X");
		Element yElement = doc.createElement("Y");
		Element widthElement = doc.createElement("Width");
		Element heightElement = doc.createElement("Height");
		
		Text xText = doc.createTextNode("" + this.getBounds().x);
		Text yText = doc.createTextNode("" + this.getBounds().y);
		Text widthText = doc.createTextNode("" + this.getBounds().width);
		Text heightText = doc.createTextNode("" + this.getBounds().height);
		
		xElement.appendChild(xText);
		yElement.appendChild(yText);
		widthElement.appendChild(widthText);
		heightElement.appendChild(heightText);
		
		pos.appendChild(xElement);
		pos.appendChild(yElement);
		pos.appendChild(widthElement);
		pos.appendChild(heightElement);
		
		root.appendChild(pos);
		
		return xml;
	}
}
